﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AppEnvironment.Lib
{
    //example singleton implementation
    /*
    public class MySingleton : Singleton<MySingleton>
    {
       private MySingleton() { } //must have private constructor for singleton

       public void DoStuff()
       {
          Console.WriteLine("instance method doing stuff");
       }
    }
    */

    /// <summary>
    /// Derive your singleton class from this, and give it a private constructor
    /// </summary>
    /// <typeparam name="T">T must be the same as your concrete class, 
    /// eg:  class MySingleton : Singleton&lt;MySingleton&gt;</typeparam>
    public abstract class Singleton<T>
       where T : class
    {
        //good article about various singleton patterns: http://www.yoda.arachsys.com/csharp/singleton.html
        //generic implementation adapted from: http://www.codeproject.com/cs/design/GenericSingletonPattern.asp

        private static class SingleInstance
        {
            // Explicit static constructor to tell C# compiler
            // not to mark type as beforefieldinit
            static SingleInstance()
            {
            }

            //thread-safe, lazy, created once only, via private constructor
            internal static readonly T Instance =
              typeof(T).InvokeMember(typeof(T).Name,
                     System.Reflection.BindingFlags.CreateInstance |
                     System.Reflection.BindingFlags.Instance |
                     System.Reflection.BindingFlags.NonPublic, //looks for non-public constructor
                     null, null, null) as T;
        }

        protected static T InstanceProtected { get { return SingleInstance.Instance; } }
    }

    
}
